﻿using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using SHomeWorkshop.LunarConcept.Widgets;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarMind.ConceptWidgets;

namespace SHomeWorkshop.LunarConcept.Adorners
{
    /// <summary>
    /// 创建时间：2012年8月4日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：用以用在PageEditor的EditAreaRectangle上的Adorner。用来显示网格线，包括：米字格、回宫格、田字格、空……
    ///           2014年2月5日新增两行、两列、三行、三列、四格、九宫格，用于规划版面。
    /// </summary>
    public class PageEditAreaGridAdorner : Adorner
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [构造方法]
        /// </summary>
        /// <param name="adornedElement">应传入PageEditor的BaseCanvas。</param>
        /// <param name="masterPageEditor">使用此装饰器的页面编辑器。</param>
        public PageEditAreaGridAdorner(UIElement adornedElement, PageEditorReader masterPageEditor)
            : base(adornedElement)
        {
            this.masterPageEditor = masterPageEditor;

            //终于解决了选定装饰器中线条宽度为2而不是1像素的问题！！！
            this.SnapsToDevicePixels = true;
            this.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private PageEditorReader masterPageEditor;
        /// <summary>
        /// [只读]使用此装饰器的页面。
        /// </summary>
        public PageEditorReader MasterPageEditor
        {
            get { return masterPageEditor; }
        }

        #endregion

        #region 方法=========================================================================================================

        /// <summary>
        /// 绘制装饰器。
        /// </summary>
        protected override void OnRender(DrawingContext drawingContext)
        {
            if (this.Visibility != Visibility.Visible) return;

            if (this.masterPageEditor == null || this.masterPageEditor == null) return;

            Brush assistGridFormBrush = this.masterPageEditor.AssistGridStroke;
            Pen pen = new Pen(assistGridFormBrush, 1);
            pen.StartLineCap = pen.EndLineCap = PenLineCap.Square;

            Rect adornedElementRect = FormatRect(new Rect(this.AdornedElement.RenderSize));
            switch (this.masterPageEditor.AssistGridForm)
            {
                case AssistGridForm.None: return;
                case AssistGridForm.Box:
                    {
                        pen.DashStyle = DashStyles.Dot;
                        drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        break;
                    }
                case AssistGridForm.Grid:
                    {
                        #region 画网格
                        pen.DashStyle = DashStyles.Solid;
                        //Pen vPen = new Pen(pen.Brush, 1) { DashStyle = DashStyles.Dot };

                        //外框。
                        //drawingContext.DrawRectangle(null, pen, adornedElementRect);

                        double startX, startY, endX, endY; int rowsCount, columnsCount;
                        //每个Cell都是48*48，这样正好画正斜线和十字线。

                        rowsCount = (int)(adornedElementRect.Height / 48);
                        columnsCount = (int)(adornedElementRect.Width / 48);

                        startX = (int)(adornedElementRect.Left + (adornedElementRect.Width - columnsCount * 48) / 2);
                        startY = (int)(adornedElementRect.Top + (adornedElementRect.Height - rowsCount * 48) / 2);

                        endX = startX + columnsCount * 48;
                        endY = startY + rowsCount * 48;

                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(endX, startY));
                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(startX, endY));

                        //画竖线。
                        double xOffset = startX;
                        double yOffset = startY;
                        for (int ix = 0; ix < columnsCount; ix++)
                        {
                            //for (int i = 1; i < 4; i++)//有延迟
                            //{
                            //    double x = xOffset + i * 12;
                            //    drawingContext.DrawLine(vPen, new Point(x, startY), new Point(x, endY));
                            //}

                            xOffset += 48;
                            drawingContext.DrawLine(pen, new Point(xOffset, startY), new Point(xOffset, endY));
                        }

                        //画横线。
                        for (int iy = 0; iy < rowsCount; iy++)
                        {
                            //for (int i = 1; i < 4; i++)//有延迟
                            //{
                            //    double y = yOffset + i * 12;
                            //    drawingContext.DrawLine(vPen, new Point(startX, y), new Point(endX, y));
                            //}

                            yOffset += 48;
                            drawingContext.DrawLine(pen, new Point(startX, yOffset), new Point(endX, yOffset));
                        }

                        break;
                        #endregion
                    }
                case AssistGridForm.Huitian:
                case AssistGridForm.Huizi:
                    {
                        #region 画回宫格和回宫田字格
                        pen.DashStyle = DashStyles.Solid;

                        //外框。
                        //drawingContext.DrawRectangle(null, pen, adornedElementRect);

                        Pen vPen = new Pen(pen.Brush, 1) { DashStyle = DashStyles.Dot };

                        double startX, startY, endX, endY; int rowsCount, columnsCount;
                        //每个Cell都是48*48，这样正好画正斜线和十字线。

                        rowsCount = (int)(adornedElementRect.Height / 48);
                        columnsCount = (int)(adornedElementRect.Width / 48);

                        startX = (int)(adornedElementRect.Left + (adornedElementRect.Width - columnsCount * 48) / 2);
                        startY = (int)(adornedElementRect.Top + (adornedElementRect.Height - rowsCount * 48) / 2);

                        endX = startX + columnsCount * 48;
                        endY = startY + rowsCount * 48;

                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(endX, startY));
                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(startX, endY));

                        //画竖线。
                        double xOffset = startX;
                        double yOffset = startY;

                        if (this.masterPageEditor.AssistGridForm == AssistGridForm.Huitian)
                        {
                            for (int ix = 0; ix < columnsCount; ix++)
                            {
                                double x = xOffset + 24;
                                drawingContext.DrawLine(vPen, new Point(x, startY), new Point(x, endY));

                                xOffset += 48;
                                drawingContext.DrawLine(pen, new Point(xOffset, startY), new Point(xOffset, endY));
                            }
                        }
                        else
                        {
                            for (int ix = 0; ix < columnsCount; ix++)
                            {
                                xOffset += 48;
                                drawingContext.DrawLine(pen, new Point(xOffset, startY), new Point(xOffset, endY));
                            }
                        }

                        //画横线。
                        if (this.masterPageEditor.AssistGridForm == AssistGridForm.Huitian)
                        {
                            for (int iy = 0; iy < rowsCount; iy++)
                            {
                                double y = yOffset + 24;
                                drawingContext.DrawLine(vPen, new Point(startX, y), new Point(endX, y));

                                yOffset += 48;
                                drawingContext.DrawLine(pen, new Point(startX, yOffset), new Point(endX, yOffset));
                            }
                        }
                        else
                        {
                            for (int iy = 0; iy < rowsCount; iy++)
                            {
                                yOffset += 48;
                                drawingContext.DrawLine(pen, new Point(startX, yOffset), new Point(endX, yOffset));
                            }
                        }

                        xOffset = startX;
                        yOffset = startY;

                        for (int ix = 0; ix < columnsCount; ix++)
                        {
                            yOffset = startY;
                            for (int iy = 0; iy < rowsCount; iy++)
                            {
                                drawingContext.DrawRectangle(null, pen, new Rect(xOffset + 14, yOffset + 8, 20, 32));
                                yOffset += 48;
                            }
                            xOffset += 48;
                        }

                        break;
                        #endregion
                    }
                case AssistGridForm.Tianzi:
                    {
                        #region 画田字格
                        pen.DashStyle = DashStyles.Solid;

                        //外框。
                        //drawingContext.DrawRectangle(null, pen, adornedElementRect);

                        Pen vPen = new Pen(pen.Brush, 1) { DashStyle = DashStyles.Dot };

                        double startX, startY, endX, endY; int rowsCount, columnsCount;
                        //每个Cell都是48*48，这样正好画正斜线和十字线。

                        rowsCount = (int)(adornedElementRect.Height / 48);
                        columnsCount = (int)(adornedElementRect.Width / 48);

                        startX = (int)(adornedElementRect.Left + (adornedElementRect.Width - columnsCount * 48) / 2);
                        startY = (int)(adornedElementRect.Top + (adornedElementRect.Height - rowsCount * 48) / 2);

                        endX = startX + columnsCount * 48;
                        endY = startY + rowsCount * 48;

                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(endX, startY));
                        drawingContext.DrawLine(pen, new Point(startX, startY), new Point(startX, endY));

                        //画竖线。
                        double xOffset = startX;
                        double yOffset = startY;
                        for (int ix = 0; ix < columnsCount; ix++)
                        {
                            double x = xOffset + 24;
                            drawingContext.DrawLine(vPen, new Point(x, startY), new Point(x, endY));

                            xOffset += 48;
                            drawingContext.DrawLine(pen, new Point(xOffset, startY), new Point(xOffset, endY));
                        }

                        //画横线。
                        for (int iy = 0; iy < rowsCount; iy++)
                        {
                            double y = yOffset + 24;
                            drawingContext.DrawLine(vPen, new Point(startX, y), new Point(endX, y));

                            yOffset += 48;
                            drawingContext.DrawLine(pen, new Point(startX, yOffset), new Point(endX, yOffset));
                        }
                        break;
                        #endregion
                    }
                case AssistGridForm.TwoLine:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        int h = (int)adornedElementRect.Height / 3;

                        if (h > 10)
                        {
                            var topRect = new Rect(adornedElementRect.X, adornedElementRect.Y, adornedElementRect.Width, h - 10);
                            drawingContext.DrawRectangle(null, pen, topRect);

                            var bottomRect = new Rect(adornedElementRect.X, adornedElementRect.Y + h, adornedElementRect.Width, adornedElementRect.Height - h);
                            drawingContext.DrawRectangle(null, pen, bottomRect);
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
                case AssistGridForm.TwoColumn:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        int w = (int)adornedElementRect.Width / 3;

                        if (w > 10)
                        {
                            var topRect = new Rect(adornedElementRect.X, adornedElementRect.Y, w - 10, adornedElementRect.Height);
                            drawingContext.DrawRectangle(null, pen, topRect);

                            var bottomRect = new Rect(adornedElementRect.X + w, adornedElementRect.Y, adornedElementRect.Width - w, adornedElementRect.Height);
                            drawingContext.DrawRectangle(null, pen, bottomRect);
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
                case AssistGridForm.ThreeLine:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        int h = (int)adornedElementRect.Height / 4;

                        if (h > 10)
                        {
                            var topRect = new Rect(adornedElementRect.X, adornedElementRect.Y, adornedElementRect.Width, h - 10);
                            drawingContext.DrawRectangle(null, pen, topRect);

                            var centerRect = new Rect(adornedElementRect.X, adornedElementRect.Y + h, adornedElementRect.Width, adornedElementRect.Height / 2);
                            drawingContext.DrawRectangle(null, pen, centerRect);

                            var bottomRect = new Rect(adornedElementRect.X, adornedElementRect.Bottom - h + 10, adornedElementRect.Width, h - 10);
                            drawingContext.DrawRectangle(null, pen, bottomRect);
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
                case AssistGridForm.ThreeColumn:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        int w = (int)adornedElementRect.Width / 4;

                        if (w > 10)
                        {
                            var topRect = new Rect(adornedElementRect.X, adornedElementRect.Y, w - 10, adornedElementRect.Height);
                            drawingContext.DrawRectangle(null, pen, topRect);

                            var centerRect = new Rect(adornedElementRect.X + w, adornedElementRect.Y, adornedElementRect.Width / 2, adornedElementRect.Height);
                            drawingContext.DrawRectangle(null, pen, centerRect);

                            var bottomRect = new Rect(adornedElementRect.Right - w + 10, adornedElementRect.Y, w - 10, adornedElementRect.Height);
                            drawingContext.DrawRectangle(null, pen, bottomRect);
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
                case AssistGridForm.FourCell:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        int w = (int)adornedElementRect.Width / 2;
                        int h = (int)adornedElementRect.Height / 2;

                        if (w > 5 && h > 5)
                        {
                            int ws = w - 5; int hs = h - 5;

                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X, adornedElementRect.Y, ws, hs));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w + 5, adornedElementRect.Y, ws, hs));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X, adornedElementRect.Y + h + 5, ws, hs));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w + 5, adornedElementRect.Y + h + 5, ws, hs));
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
                case AssistGridForm.NineCell:
                    {
                        pen.DashStyle = DashStyles.Dot;

                        if (adornedElementRect.Width > 20 && adornedElementRect.Height > 20)
                        {
                            int w = (int)(adornedElementRect.Width - 20) / 3;
                            int h = (int)(adornedElementRect.Height - 20) / 3;

                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X, adornedElementRect.Y, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w + 10, adornedElementRect.Y, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w * 2 + 20, adornedElementRect.Y, w, h));

                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X, adornedElementRect.Y + h + 10, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w + 10, adornedElementRect.Y + h + 10, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w * 2 + 20, adornedElementRect.Y + h + 10, w, h));

                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X, adornedElementRect.Y + h * 2 + 20, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w + 10, adornedElementRect.Y + h * 2 + 20, w, h));
                            drawingContext.DrawRectangle(null, pen, new Rect(adornedElementRect.X + w * 2 + 20, adornedElementRect.Y + h * 2 + 20, w, h));
                        }
                        else
                        {
                            drawingContext.DrawRectangle(null, pen, adornedElementRect);
                        }
                        break;
                    }
            }

        }

        /// <summary>
        /// 对矩形的X/Y/Width/Height四舍五入。
        /// </summary>
        /// <param name="srcRect">源Rect。</param>
        /// <returns></returns>
        public static Rect FormatRect(Rect srcRect)
        {
            Rect newRect = new Rect(
                (int)(srcRect.X + 0.5),
                (int)(srcRect.Y + 0.5),
                (int)(srcRect.Width + 0.5),
                (int)(srcRect.Height + 0.5)
                );
            return srcRect;
        }

        #endregion
    }
}
